﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace IOT
{
    public class IOTMessage<T>
    {
        public delegate bool ReplyHitHandler(Span<byte> data);
        public delegate void ReceiveHandler(IOTStateObject<T> state, Span<byte> data, object cdata);

        /// <summary>
        /// 只允许内部调用
        /// </summary>
        internal IOTMessage()
        {

        }

        /// <summary>
        /// 是否需要逆变器应答
        /// </summary>
        public bool NeedReply { get; set; } = true;

        /// <summary>
        /// 要发送给逆变器的数据
        /// </summary>
        public byte[] Package { get; set; }

        /// <summary>
        /// 内部维护，是否收到了设备的回复
        /// </summary>
        internal bool IsReply { get; set; } = false;

        /// <summary>
        /// 委托，用于判断收到的数据是否为这一包的回复，内部调用
        /// </summary>
        public ReplyHitHandler ReplyHit { get; set; }

        /// <summary>
        /// 收到数据后的回调，一般用于远程控制，如果该回调不为空，则在调用ReplyHitTest时，若返回结果为true，则执行
        /// </summary>
        public ReceiveHandler ReceiveCallback { get; set; }

        /// <summary>
        /// 用户自定义数据，在收到回调后，将作为参数传给回调函数
        /// </summary>
        public object CData { get; set; }

        /// <summary>
        /// 在接收到数据后调用，用于判断数据是否为这一包的回复，如果是这一包的回复，该调回调调回调，没有回调则将IsReply字段标记为true
        /// </summary>
        /// <param name="data"></param>
        public void ReplyHitTest(IOTStateObject<T> state, Span<byte> data)
        {
            try
            {
                if (ReplyHit == null)
                    IsReply = true;
                else
                    IsReply = ReplyHit.Invoke(data);

                if (ReceiveCallback != null && IsReply)
                {
                    ReceiveCallback.Invoke(state, data, CData);
                    ReceiveCallback = null;                 //重新置为空
                }
            }
            catch (Exception)
            {
                throw;
            }
        }
    }
}
